<?php

class MisEpisodeHelper
{
    private $error_msg = array();
    private $receiveJobs = array();
	private $new;
	private $link_list = array();
	private $change_logs=array();
  
    public function import($job)
    {
		$this->new = FALSE;
		$this->link_list = array();
		$this->change_logs = array();
        $pid = $job['PGM_ID'];
        $mis_api  = new MisApi();
        $relation = array();
        $this->error_msg['episode'] = '';
        $zh_lang = language::getLanguageID(AC::LANGUAGE_ZH);
        $en_lang = language::getLanguageID(AC::LANGUAGE_EN);
        
        $pdes_pid = mis_pdes::getRelation(array(
            'co_code' => $job['CO_CODE'],
            'type' => 'programme',
            'mis_id' => $pid));
        
        $pdes_pid = isset($pdes_pid[0]['pdes_id']) ? $pdes_pid[0]['pdes_id'] : '';
    
        $pdes_pid = programme_cpl::checkCpl($pid,$job['CO_CODE']);
        if(!empty($job)) {
			// by donald @ 2011-04-26
			$synopsis = $mis_api->getDataByApi('getEpiSynopsisDetails', array(
				'CO_CODE' => $job['CO_CODE'],
				'PGM_ID' => $job['PGM_ID'],
				'EPI_ID' => $job['EPI_ID']
			));

			$this->error_msg = array('infos'=>'','episode'=>'','cast'=>'');
            $epi_id = $job['EPI_PID'];
            $pdata = mis_pdes::getRelation(array(
                'co_code' => $job['CO_CODE'],
                'type' => 'episode',
                'mis_eid' => $epi_id));
            $old_episode = Model::$dbo['r']->findInstance('episode',array($pdata[0]['pdes_id']));
            $old_episode_language = Model::$dbo['r']->findInstance('episode_language',array($pdata[0]['pdes_id'],$zh_lang));
            $old_episode_language_en = Model::$dbo['r']->findInstance('episode_language',array($pdata[0]['pdes_id'],$en_lang));

            if(!empty($pdata)) {
                foreach($pdata as $item) {
                    $relation = array(
                        'co_code' => $job['CO_CODE'],
                        'type'    => 'episode',
                        'mis_id'  => $item['mis_id'],
                        'mis_eid' => $item['mis_eid'],
                        'mis_pid' => $item['mis_pid'],
                        'pdes_id' => $item['pdes_id'],
                        'pdes_eid'=> $item['pdes_eid'],
                        'pdes_pid'=> $item['pdes_pid']
                    );
                    $eid = $item['pdes_eid'];
                    $pdes_data = Model::$dbo['r']->findInstance('episode',array($eid));
                    $pdes_onair_episode_no = $pdes_data->onair_episode_no;
                    $mis_data = $mis_api->getDataByApi('getEpisodeDetails',array('EPI_PID'=>$item['mis_eid']));
				//	error_log($mis_data->EPI_ID);
                    $new_ret = $this->getDiffResult($mis_data,$pdes_data,$job);
                    if (empty($new_ret)) {
                        //continue;
                        return FALSE;
                    }
                    $new_ret->status = AC::STATUS_NEW; 
                    $new_ret->onair_episode_no = $pdes_onair_episode_no;

                    if($new_ret) {
						if ($this->new === TRUE) {
	                        Model::$dbo['w']->save($new_ret);

							# change_log
							$this->change_logs[] = array(
								'type'=>'episode',
								'keys'=>array('id'=>$new_ret->id),
								'is_active'=>1,
								'is_publish'=>0,
								'episode'=>array($new_ret->id)
							);
						}
                        $e_id = $new_ret->id;
                    }

                    $this->replaceEpisodeLanguage($eid,$mis_data, $synopsis);
                    $this->setReceiveJob($job);
					$this->link_list[] = sprintf(AC::$mis_view_url, 'episode', $eid);
                }
            } else {
				$this->new = TRUE;
                $mis_data = $mis_api->getDataByApi('getEpisodeDetails',array('EPI_PID'=>$epi_id));
                try{
                    $diff_ret = MisMapping::getMapping('episode',$mis_data,'');
                }
                catch(MISException $e){
                    $this->error_msg['episode'] .= "\n"."Import MIS's Episode({$job['CO_CODE']}+{$job['PGM_ID']}+{$job['EPI_PID']}) failure:" .$e->getMessage();
                    return FALSE;
                }


//				if(property_exists($mis_data,'Air_Date')){
//					$diff_ret->publish_datetime = ((string)$mis_data->Air_Date->TELECAST_DATE). ' ' .((string)$mis_data->Air_Date->AIR_TIME_HHMMSS);
//					if(strtotime($diff_ret->publish_datetime) < time()){
//						$this->error_msg['episode'] .= "\nEpisode($epi_id) On Air Date Time is expired[{$diff_ret->publish_datetime}]";
//						return FALSE;
//					}
//				}else{
//					$diff_ret->publish_datetime = date('Y-m-d H:i:s');
//				}
                
                $e_id = $this->replaceEpisode($diff_ret, $pdes_pid, $mis_data);
                if($e_id) {
                    $this->replaceEpisodeLanguage($e_id,$mis_data, $synopsis);
                    $pdes_pid  = $this->getProgrammeByEpisodeId($e_id); 
                    $type = 'episode';
                    $relation = array(
                        'co_code' => $job['CO_CODE'],
                        'type'    => $type,
                        'mis_id'  => $epi_id,
                        'mis_eid' => $epi_id,
                        'mis_pid' => $pid,
                        'pdes_id' => $e_id,
                        'pdes_eid'=> $e_id,
                        'pdes_pid'=> $pdes_pid
                    );
                    $exist = mis_pdes::getRelation(array(
                        'co_code' => $job['CO_CODE'],
                        'type' => 'episode',
                        'mis_eid' => $epi_id));
                    if(!$exist) {
                        $r =  mis_pdes::updateRelation($relation);
                    }
                    $this->setReceiveJob($job);
                } else {
                    $this->error_msg['episode'] .= "\ncan not insert episode to pdes form mis episode id {$epi_id}";
                    return FALSE;
                } 
            }

            $mis_data->CASTS = $this->updateCasts($relation,$epi_id,$mis_api,$mis_data);
            $this->update_infos($relation);
            $this->update_log($e_id,$mis_data,$old_episode,$old_episode_language,$old_episode_language_en, $synopsis);
           
            return TRUE;
        } else {
            $this->error_msg['episode'] .= "\nepisode id is none";
            return FALSE;
        }
    }

    private function setReceiveJob($job)
    {
        $this->receiveJobs = array_merge($this->receiveJobs, array($job));  
    }

    public function getReceiveJobs()
    {
        return $this->receiveJobs;
    }

	public function getLinkList()
	{
		return $this->link_list;
	}

	public function getChangeLogs(){
		return $this->change_logs;
	}

    private function update_infos($relation)
    {
        $this->error_msg['infos'] = '';
        if(empty($relation)) {
            $this->error_msg['infos'] = "parameter relation is empty,update infos fail";
            return false; 
        }
      
        $mis_api  = new MisApi();
        $infos = array(
            'Song'        =>array('getiSongByEpisode'=>'SONG_ID'),
            'Recipe'      =>array('getiRecipeByEpisode'=>'RECIPE_ID'),
            'Product'     =>array('getiProductByEpisode'=>'PRODUCT_ID'),
            'Biography'   =>array('getiBiographyByEpisode'=>'BIOGRAPHY_ID'),
            'Award'       =>array('getiAwardByEpisode'=>'AWARD_ID'),
            'Address'     =>array('getiAddressByEpisode'=>'ADDRESS_ID'),
            'Pageant'     =>array('getiPageantByEpisode'=>'PAGEANT_ID'),
            'GeneralInfo' =>array('getiGeneral_infoByEpisode'=>'GENERAL_ID'),
            'QA'          =>array('getiQAByEpisode'=>'QA_ID'),
        );
        foreach($infos as $info_obj => $info) {   
            foreach($info as $key => $val) {
                $api_name = $key;
                $id = $val;
            }
            $xml_obj = $mis_api->getDataByApi($api_name, array(
                'EPI_PID' => $relation['mis_eid'],
                'START_SEQ' => 1,
                'NUM' => 9999));
            $ids = $this->get_infos_ids($xml_obj,$id);
            $obj = 'MisInfo'.$info_obj;
            $object = new $obj($relation);
            $object->import($ids);
			$this->link_list = array_merge($this->link_list, $object->getLinkList());
            $this->error_msg['infos'] .= "\n".trim($object->getErrorMessage());
			# change_log
			$this->change_logs = array_merge($this->change_logs,$object->getChangeLogs());
        }
    }

    private function get_infos_ids($xml_obj,$info)
    {
        $ids = array();
        if(!empty($xml_obj)) {
            foreach($xml_obj->$info as $p) {
                $ids[] = (string)$p;
            }
        }
        return $ids;
    }
    
    public function getErrorMessage(){
        return empty($this->error_msg) ? '' :trim( implode("\n",$this->error_msg));
    }

    private function update_log($e_id,$mis_data,$old_episode,$old_episode_language,$old_episode_language_en, $synopsis)
    {
        $error_msg = '';
        $sync_data = array();
        $new_data = array();
        $sql_data = array();
        $log->pdes_id   = $e_id;
        $log->type      = 'episode';

        try {
            $sql = 'select modified_at,onair_episode_no as onair_no from episode where id = :eid';
            $ret = Model::selectBySql($sql,array(':eid'=>$e_id));
            $onair_no = isset($ret[0]['onair_no']) ? $ret[0]['onair_no'] : '';
           
            $map         = MisMapping::getMapping('episode',$mis_data,'');
            $epi_lang    = MisMapping::getMapping('episode-language',$mis_data,'zh');
            $epi_lang_en = MisMapping::getMapping('episode-language',$mis_data,'en');

			// by donald @2011-04-26
			$epi_lang->description_short = !empty($synopsis->SETTOPBOX) ? $synopsis->SETTOPBOX : '';
			$epi_lang_en->description_short = !empty($synopsis->SETTOPBOX_E) ? $synopsis->SETTOPBOX_E : '';

            if(!empty($old_episode) && !empty($old_episode_language)) {
                $sync_data['Episode']   = MisMapping::formatLogData('episode',(array)$old_episode);
                $sync_data['Episode_language_zh']   = MisMapping::formatLogData('episode-language',(array)$old_episode_language,'zh');
                $sync_data['Episode_language_en']   = MisMapping::formatLogData('episode-language',(array)$old_episode_language_en,'en');
            }

			$map->onair_episode_no = $onair_no;
            $new_data['Episode']    = MisMapping::formatLogData('episode',(array)$map);
            $new_data['Episode_language_zh']   = MisMapping::formatLogData('episode-language',(array)$epi_lang,'zh');
            $new_data['Episode_language_en']   = MisMapping::formatLogData('episode-language',(array)$epi_lang_en,'en');
        } catch(MISException $e) {
            $error_msg = $e->getMessage();
            $this->error_msg['episode'] .= "\n".$e->getMessage();
        }

        if(!empty($error_msg)) {
            $log->sync_data = '[]';
            $log->mis_data = '[]';
            $log->status    =  0;
            $log->message   = !isset($this->error_msg['episode']) ? '' : trim( $this->error_msg['episode']);
        } else {
            $log->sync_data = json_encode($sync_data);
            $log->mis_data = json_encode($new_data) ;
            $log->status    = $e_id > 0;
            $log->message   = !isset($this->error_msg['episode']) ? '' : trim( $this->error_msg['episode']);
            $log->modified_at = date('Y-m-d H:i:s');
        }

        $result =  mis_log::update($log);

        return $result;
    }

    private function filterArray($array)
    {
        if(is_object($array)) {
            $array = (array)$array;
        }
        $ret = array();
        foreach($array as $key => $val) {
            $val = (array)$val;
            $ret[$key] = $val[0];
        }
        return $ret;
    }

    private function updateCasts($rel,$eid,$mis_api,$mis_data)
    {
        $this->error_msg['cast'] = '';
        if(empty($rel)) {
            $this->error_msg['cast'] = "parameter relation is empty,update casts fail ";
            return false; 
        }
       // var_dump($eid);
        $mis_data = $mis_api->getDataByApi('getCastByEpisode',array('EPI_PID'=>$eid,'START_SEQ'=>1,'NUM'=>9999));
        $casts = array();
        $episode_casts = array();

		$new_casts = array();
		$cast = new MisCastHelper($rel);

        if (!empty($mis_data)) {
            foreach($mis_data as $cast_data) {
                $attr = $cast_data->GROUPS_ID->attributes();
                $group_id = (int)$attr->GROUPS_ID;

				try{
					$cast_role_id = MisMapping::getCastRoleMapping($group_id);
				}catch(MISException $e){
					$this->error_msg['cast'] .= "\n".$e->getMessage();
					continue;
				}

				$cast->import(array((int)$cast_data->CASTS_ID => $cast_role_id));
				MisCommon::mergeCast($new_casts, $cast->getInsertedIds());
				MisCommon::mergeCast($new_casts, $cast->getUpdatedIds());
            }
        }

	    $episode = new episode();
        $new_episode = $episode->get($rel['pdes_eid']);
		$old_casts = json_decode($new_episode->casts, TRUE);
		if (is_array($old_casts)) {
			MisCommon::mergeCast($new_casts, $old_casts);
		}
		MisCommon::uniqueCast($new_casts);
		$new_episode->casts = json_encode($new_casts);
        $new_episode->modified_at = date('Y-m-d H:i:s');

		if ($this->new === TRUE) {
        	$rs = Model::$dbo['w']->save($new_episode);
        	if (!$rs) {
        	    $this->error_msg['cast'] .= "update casts to episode({$rel['pdes_eid']}) error";
			}
		}

		# change_log
		$this->change_logs = array_merge($this->change_logs,$cast->getChangeLogs());

		return $new_episode->casts; 
    }

    private function getProgrammeByEpisodeId($eid)
    {
        $sql = 'select programme_id as pid from episode where id = :eid';
        $ret = Model::selectBySql($sql,array(':eid'=>$eid));
        return empty($ret) ? FALSE : $ret[0]['pid'];
    
    }

    private function replaceEpisode($diff_ret,$pid, $mis_data)
    {
        if(empty($pid)) {
            return false;
        }
       
        $mis_api  = new MisApi();
        $episode = new episode();
        $episode->set($episode);
        $episode->programme_id = $pid;
        $episode->expire_datetime = '2029-12-31 23:59:59';
        $episode->created_at = date("Y-m-d H:i:s", $_SERVER['REQUEST_TIME']);
        $episode->created_by = CommonUtils::get_user();
        $episode->modified_at = $episode->created_at;
        $episode->modified_by = $episode->created_by;
        $episode->folders = CommonUtils::init_folder("episode");
        $episode->available_tag_types = CommonUtils::get_allow_tags("episode");
        $episode->highlighted_cast_roles = CommonUtils::get_highlight_role("episode");
        $episode->status = AC::STATUS_NEW;
// bug 4136        
//      $episode->casts = $this->fetch_programme_cast($pid);
        foreach($diff_ret as $diff_key => $diff_val) {
            if (array_key_exists($diff_key, $episode) && $diff_val != null) {
                $episode->$diff_key = $diff_val;
            }
        }
        $t = strtotime($episode->publish_datetime) - 24*60*60;
        $episode->publish_datetime = date('Y-m-d H:i:s',$t);

        $sql_onair = 'select id,onair_episode_no as air_no from episode where programme_id = :pid and onair_episode_no = :onair';
        $ret_onair =  Model::selectBySql($sql_onair,array(':onair'=>$diff_ret->onair_episode_no,':pid'=>$pid));
        if($ret_onair) {
            $pdes_data = Model::$dbo['r']->findInstance('episode',array($ret_onair[0]['id']));
            $new_ret = $this->getDiffResult($mis_data,$pdes_data);
            if ($new_ret) {
                $ret = Model::$dbo['w']->save($new_ret);
				# change_log
				$_eid = (is_numeric($ret) && $ret>1) ? $ret : $new_ret->id;
				$this->change_logs[] = array(
					'type'=>'episode',
					'keys'=>array('id'=>$_eid),
					'is_active'=>1,
					'is_publish'=>0,
					'episode'=>array($_eid)
				);
            }
            $eid = $ret ? $new_ret->id : '' ;
        } else {
            $sql = 'select max(onair_episode_no) as onair_no from episode where programme_id = :pid';
            $ret = Model::selectBySql($sql,array(':pid'=>$pid));
            //append by  Keith
			$onair_no = $mis_data->EPI_ID;
			//$onair_no = ($ret[0]['onair_no'] < 10000000) ? 10000000 : $ret[0]['onair_no'] + 1;
			//keith change $onair_no
			//system with follow MIS episode no. doesn't have any changes
            $episode->onair_episode_no  = $onair_no;
			//var_dump($episode);
            $eid = mis_pdes::replace($episode);
        }
        return $eid;
    }

    private function replaceEpisodeLanguage($eid,$mis_obj, $synopsis)
    {
        $zh_lang = language::getLanguageID(AC::LANGUAGE_ZH);
        $en_lang = language::getLanguageID(AC::LANGUAGE_EN);

        try {
            $epi_lang    = MisMapping::getMapping('episode-language',$mis_obj,'zh');
            $epi_lang_en = MisMapping::getMapping('episode-language',$mis_obj,'en');

            if(!is_object($epi_lang) || !is_object($epi_lang_en)) {
                $this->error_msg['episode'] .= "\nMisMapping get episode language mapping fail";
                return false;
            } else {
                $exist = episode_language::getLangEpisodeByID($eid,$zh_lang);
                if(!$exist) {
                    $episode_language = new episode_language();
                    $episode_language->episode_id = $eid;
                    $episode_language->language_id = $zh_lang;
                    $episode_language->title = $epi_lang->title;
                    $episode_language->description = $epi_lang->description;
                    $episode_language->description_short = !empty($synopsis->SETTOPBOX) ? $synopsis->SETTOPBOX : ''; 
                    $episode_language->editor_message = $epi_lang->editor_message;
					if ($this->new === TRUE) {
	                    Model::$dbo['w']->save($episode_language);
						# change_log
						$this->change_logs[] = array(
							'type'=>'episode-language',
							'keys'=>array('episode_id'=>$eid,'language_id'=>$zh_lang),
							'is_active'=>1,
							'is_publish'=>0,
							'episode_id'=>array($eid)
						);
					}

                    $episode_language->language_id = $en_lang;
                    $episode_language->title = $epi_lang_en->title;
                    $episode_language->description = $epi_lang_en->description;
                    $episode_language->description_short = !empty($synopsis->SETTOPBOX_E) ? $synopsis->SETTOPBOX_E : ''; 
                    $episode_language->editor_message = $epi_lang_en->editor_message;
					if ($this->new === TRUE) {
	                    Model::$dbo['w']->save($episode_language);
						# change_log
						$this->change_logs[] = array(
							'type'=>'episode-language',
							'keys'=>array('episode_id'=>$eid,'language_id'=>$en_lang),
							'is_active'=>1,
							'is_publish'=>0,
							'episode_id'=>array($eid)
						);
					}
                } else {
                    $episode_language = Model::$dbo['r']->findInstance('episode_language',array($eid,$zh_lang));
                    $episode_language->title = $epi_lang->title;
                    $episode_language->description = $epi_lang->description;
                    $episode_language->description_short = !empty($synopsis->SETTOPBOX) ? $synopsis->SETTOPBOX : ''; 
                    $episode_language->editor_message = $epi_lang->editor_message;
					if ($this->new === TRUE) {
	                    Model::$dbo['w']->save($episode_language);
						# change_log
						$this->change_logs[] = array(
							'type'=>'episode-language',
							'keys'=>array('episode_id'=>$eid,'language_id'=>$zh_lang),
							'is_active'=>1,
							'is_publish'=>0,
							'episode_id'=>array($eid)
						);
					}

                    $episode_language = Model::$dbo['r']->findInstance('episode_language',array($eid,$en_lang));
                    $episode_language->title = $epi_lang_en->title;
                    $episode_language->description = $epi_lang_en->description;
                    $episode_language->description_short = !empty($synopsis->SETTOPBOX_E) ? $synopsis->SETTOPBOX_E : ''; 
                    $episode_language->editor_message = $epi_lang_en->editor_message;
					if ($this->new === TRUE) {
	                    Model::$dbo['w']->save($episode_language);
						# change_log
						$this->change_logs[] = array(
							'type'=>'episode-language',
							'keys'=>array('episode_id'=>$eid,'language_id'=>$en_lang),
							'is_active'=>1,
							'is_publish'=>0,
							'episode_id'=>array($eid)
						);
					}
                }
            }
        } catch(MISException $e) {
            $this->error_msg['episode'] .= "\n".$e->getMessage();
            return false;
        }
    }

// bug 4136    
//    /**
//    ** fetch programme's cast to fill episode
//     **/
//    private function fetch_programme_cast($pid)
//    {
//        $programme = new programme();
//        $programme_detail = $programme->get($pid);
//        return $programme_detail->casts;
//    }

    private function getDiffResult($mis_data,$pdes_data,$job = '')
    {
        $tmp = array();
        try{
            $map = MisMapping::getMapping('episode',$mis_data,'');
        } catch(MISException $e){
            $this->error_msg['episode'] .= "\n"."Import MIS's Episode({$job['CO_CODE']}+{$job['PGM_ID']}+{$job['EPI_PID']}) failure:" .$e->getMessage();
            return false;
        }

        if(empty($pdes_data) || empty($mis_data)) {
            $this->error_msg['episode'] .= "\nepisode in pdes is empty or mis record is empty";
            return false;
        }
        foreach($map as $map_key => $map_val) {
            if (array_key_exists($map_key, $pdes_data)) {
                $map_val = (array)$map_val;
                $tmp[$map_key] = $map_val[0];
            }
        }
       
        $sql = 'select onair_episode_no as air_no from episode where programme_id = :pid and  onair_episode_no = :air';
        $ret = Model::selectBySql($sql,array(':pid'=>$pdes_data->programme_id,':air'=>$tmp['onair_episode_no']));
        if(empty($ret)) {
            $pdes_data->onair_episode_no = $tmp['onair_episode_no'];
        }
        $pdes_data->publish_datetime = $tmp['publish_datetime'];
        $pdes_data->average_rating = $tmp['average_rating'];
        $pdes_data->created_by = $tmp['created_by'];
        $pdes_data->modified_by = $tmp['modified_by'];

        return $pdes_data;
    }
}
?>
